#include "dbservice.h"
#include <QFile>
#include "./tools/database/dataaccessor.h"
#include <QVector>
#include "./tools/database/dbqueryresult.h"
#include "./entities/constants.h"
#include <QCoreApplication>

DBService& DBService::getInstance()
{
    static DBService instance;
    return instance;
}

DBService::DBService(QObject *parent)
    : QObject{parent}
{
    m_db = QSqlDatabase::addDatabase("QSQLITE");

}

DBService::~DBService()
{
    if (m_db.isOpen())
    {
        m_db.close();
    }
}


// 初始化数据库
bool DBService::initializeDB(const QString &dbName, const QString password)
{
    // 1. 如果当前数据库连接已打开，先关闭它
    if (m_db.isOpen()) {
        qDebug() << "Closing existing database...";
        m_db.close();
    }

    // 2. 检查这个新的数据库是否存在
    fileName = QCoreApplication::applicationDirPath() + "/" + dbName + ".sqlite";
    qDebug() << "absolute path:" << fileName;
    bool dbExisted = dbIsExisted();

    // 3. 如果数据库不存在会自动创建
    m_db.setDatabaseName(fileName);
    if (!m_db.open())
    {
        qDebug() << "open database failed";
        return false;
    }

    // 4. 不存在则创建数据表
    if (!dbExisted)
    {
        bool createTablesSuccess = createTables();
        if (createTablesSuccess)
        {
            qDebug() << "create tables successful";
        }
        else
        {
            qDebug() << "create tables failed";
            return false;
        }
    }
    return true;
}



// private:

// 判断数据库是否存在
bool DBService::dbIsExisted() const
{
    QFile file(fileName);
    bool existed = file.exists();
    if (existed)
    {
        qDebug() << "db is existed.";
    }
    else
    {
        qDebug() << "db is not existed.";
    }
    return existed;
}

// 创建数据库
bool DBService::createTables()
{
    if (!DataAccessor::createTables(m_db))
    {
        return false;
    }
    return true;
}

// 加载本地数据
void DBService::loadLocalData()
{
    loadNewFriendApplication();
    loadFriendship();
    // loadChatMessage();
}

// 加载新好友申请
void DBService::loadNewFriendApplication()
{
    // 取出所有好友申请
    QVector<FriendApplication> results;
    if (!DataAccessor::findAllFriendApplications(m_db, results))
    {
        qDebug() << "获取好友申请失败";
        return;
    }

    for (FriendApplication fa: results)
    {
        QString friendId = QString::number(fa.applicantId);
        FriendVerifyStatus status = static_cast<FriendVerifyStatus>(fa.status);
        emit localNewFriendApplicationReady(friendId, fa.nickname, fa.verifiyInfo,
                                    fa.createTime, fa.serverId, fa.alias, status);
    }

}

// 加载好友关系
void DBService::loadFriendship()
{
    // 取出所有好友关系
    QVector<Friendship> results;
    if (!DataAccessor::findAllFriendships(m_db, results))
    {
        qDebug() << "获取好友申请失败";
        return;
    }

    for (Friendship f: results)
    {
        QString friendId = QString::number(f.friendId);
        emit friendshipReady(friendId, f.nickname, f.alias, f.createTime);
    }
}

// public slots


void DBService::initLocalDB(const QString userId, const QString password)
{
    QString dbName = userId;
    bool isSuccess = initializeDB(dbName, password);
    qDebug() << isSuccess;
    if (isSuccess)
    {
        // 加载本地数据库
        loadLocalData();
        // 发送消息告诉UI线程，本地数据全部加载完毕
        emit dbSuccessfulLoaded();
    }

}

void DBService::refreshNewFriendApplicationStatus(const FriendVerifyStatus status, const QString alias, const int serverId)
{
    int status_num = static_cast<int>(status);
    if (!DataAccessor::updateStatusById(m_db, serverId, status_num, alias))
    {
        qDebug() << "更新好友申请状态失败";
        return;
    }
}

// 保存新的好友关系（之前发送的好友申请对方通过了）
void DBService::saveNewFriendship(const QString friendId, const QString nickname,
                const QString alias, const QDateTime resultTime)
{
    int friendId_num = friendId.toInt();
    if (!DataAccessor::insertNewFriendship(m_db, friendId_num, nickname, alias, resultTime));
    {
        qDebug() << "添加好友关系失败";
        return;
    }
}

void DBService::saveNewFriendApplication(const QString receiverId, const QString applicantId,
                              const QString nickname, const QString verifyInfo,
                              const QDateTime applyTime, const int id)
{
    // 1. 把收到的数据存到本地数据库
    int applicantId_num = applicantId.toInt();
    int status_num = static_cast<int>(FriendVerifyStatus::Unverified);
    if (!DataAccessor::insertNewFriendApplication(m_db, applicantId_num, nickname, verifyInfo, applyTime, id, status_num))
    {
        return;
    }
}

// 保存刚刚收到的好友聊天消息
void DBService::saveFriendSendChatMsg(const QString friendId, const QString msg, const QDateTime sendTime)
{
    int friendId_num = friendId.toInt();
    if (!DataAccessor::insertChatMsg(m_db, friendId_num, msg, sendTime, false))
    {
        qDebug() << "保存好友发来的聊天信息失败";
        return;
    }
}

// 保存自己发送给好友的聊天消息
void DBService::saveMeSendChatMsg(const QString userId, const QString friendId,
                                  const QString msg, const QDateTime sendTime)
{
    int friendId_num = friendId.toInt();
    if (!DataAccessor::insertChatMsg(m_db, friendId_num, msg, sendTime, true))
    {
        qDebug() << "保存自己发送的聊天信息失败";
        return;
    }
}

// 获取和某位好友的聊天记录（这里未来可以添加时间段参数来优化渲染内容）
void DBService::acquireChatMsg(const QString friendId)
{
    int friendId_num = friendId.toInt();
    QVector<ChatMsgQuery> results;
    if (!DataAccessor::findAllChatMsgByFriendId(m_db, friendId_num, results))
    {
        qDebug() << "获取聊天信息失败";
        return;
    }
    if (!results.size())
    {
        qDebug() << "和当前用户没有聊天记录";
        return;
    }
    for (ChatMsgQuery record: results)
    {
        QString curFriendId = QString::number(record.friendId);
        emit friendChatMsgReady(curFriendId, record.chatMsg, record.sendTime, record.isMeSend);
    }
}

// 其他人审核完毕了当前用户发起的好友申请（通过或者拒绝了当前用户）
// void DBService::refreshFriendshipApplicationFromOther(const QString friendId, const QString nickname,
//                         const QString status, const QString alias, const QDateTime resultTime)
// {
//     if (status == JsonValue::STATUS_REJECTED)
//     {
//         qDebug() << friendId << "对方未同意";
//         return;
//     }
//     if (!DataAccessor::insertNewFriendship(m_db, friendId.toInt(), nickname, alias, resultTime))
//     {
//         qDebug() << "插入好友关系成功";
//         return;
//     }
// }
